/*
 * Automat1.cpp
 *
 *  Created on: Apr 8, 2010
 *      Author: Stefan Obermeier
 */

#include "Automat1.h"
#include <iostream>
// #include "token.h"


using namespace std;

Automat1::Automat1() {

	eingabealphabet = 127;
	zustaende = 37;
	signs = "+-*/;()[]&<>=!{}";


	// Tabelle erzeugen

	uebergaenge= new int*[zustaende];

	for(int i=0; i<(eingabealphabet+1);i++){
			uebergaenge[i]= new int[eingabealphabet];
	}

	// Fehlerzustaende inizialisieren
	for(int i=0; i<(zustaende+1);i++){
		for(int j=0; j<eingabealphabet+1; j++){
			uebergaenge[i][j]= 20;
		}
		uebergaenge[i][13]=i;	// Bei einem CR bleibt man im alten Zustand
	}


	// Automat mit Zustandsuebergangstabelle inizialisieren.


	// Z0

	inizMixalpha(0,9);
	inizDigit(0,11);
	inizSigns(0);

	uebergaenge[0][(int)'(']= 13;
	uebergaenge[0][(int)'<']= 17;
	uebergaenge[0][(int)'p']= 1;
	uebergaenge[0][(int)'r']= 6;

	// Z1

	inizMixalpha(1,9);
	inizDigit(1,9);
	inizSigns(1);
	uebergaenge[1][(int)'(']= 13;
	uebergaenge[1][(int)'<']= 17;

	uebergaenge[1][(int)'r']= 2;


	// Z2

	inizMixalpha(2,9);
	inizDigit(2,9);
	inizSigns(2);

	uebergaenge[2][(int)'(']= 13;
	uebergaenge[2][(int)'<']= 17;

	uebergaenge[2][(int)'i']= 3;

	// Z3

	inizMixalpha(3,9);
	inizDigit(3,9);
	inizSigns(3);

	uebergaenge[3][(int)'(']= 13;
	uebergaenge[3][(int)'<']= 17;

	uebergaenge[3][(int)'n']= 4;

	// Z4

	inizMixalpha(4,9);
	inizDigit(4,9);
	inizSigns(4);

	uebergaenge[4][(int)'(']= 13;
	uebergaenge[4][(int)'<']= 17;

	uebergaenge[4][(int)'t']= 5;

	// Z5

	inizMixalpha(5,9);
	inizDigit(5,9);
	inizSigns(5);

	uebergaenge[5][(int)'(']= 13;
	uebergaenge[5][(int)'<']= 17;

	// Z6

	inizMixalpha(6,9);
	inizDigit(6,9);
	inizSigns(6);

	uebergaenge[6][(int)'(']= 13;
	uebergaenge[6][(int)'<']= 17;

	uebergaenge[6][(int)'e']= 7;

	// Z7

	inizMixalpha(7,9);
	inizDigit(7,9);
	inizSigns(7);

	uebergaenge[7][(int)'(']= 13;
	uebergaenge[7][(int)'<']= 17;

	uebergaenge[7][(int)'a']= 8;

	// Z8

	inizMixalpha(8,9);
	inizDigit(8,9);
	inizSigns(8);

	uebergaenge[8][(int)'(']= 13;
	uebergaenge[8][(int)'<']= 17;

	uebergaenge[8][(int)'d']= 10;

	//  Z9

	inizMixalpha(9,9);
	inizDigit(9,9);
	inizSigns(9);

	uebergaenge[9][(int)'(']= 13;
	uebergaenge[9][(int)'<']= 17;

	// Z10

	inizMixalpha(10,9);
	inizDigit(10,9);
	inizSigns(10);

	uebergaenge[10][(int)'(']= 13;
	uebergaenge[10][(int)'<']= 17;

	// Z11
	inizDigit(11,11);
	inizMixalpha(11,9);
	inizSigns(11);

	uebergaenge[11][(int)'(']= 13;
	uebergaenge[11][(int)'<']= 17;

	// Z12
	inizDigit(12,11);
	inizMixalpha(12,9);
	inizSigns(12);

	uebergaenge[12][(int)'(']= 13;
	uebergaenge[12][(int)'<']= 17;

	// Z13
	inizDigit(13,11);
	inizMixalpha(13,9);
	inizSigns(13);

	uebergaenge[13][(int)'(']= 13;
	uebergaenge[13][(int)'*']= 14;

	// Z14
	for(int i=0; i<128; i++){
		uebergaenge[14][i]= 14;
	}
	uebergaenge[14][(int)'*']= 15;

	// Z15
	for(int i=0; i<128; i++){
			uebergaenge[15][i]= 14;
	}
	uebergaenge[15][(int)')']= 16;

	// Z16
	inizMixalpha(16,9);
	inizDigit(16,11);
	inizSigns(17);

	// Z17
	inizMixalpha(17,9);
	inizDigit(17,11);
	inizSigns(17);

	uebergaenge[17][(int)'=']= 18;

	// Z18
	inizMixalpha(18,9);
	inizDigit(18,11);
	inizSigns(18);

	uebergaenge[18][(int)'>']= 19;

	// Z19
	inizMixalpha(19,9);
	inizDigit(19,11);
	inizSigns(19);

	// Z20 Feherzustand -> Defaultwerte

	// Z21 - Z36

	for(int i=21; i<37; i++){
		inizDigit(i,11);
		inizMixalpha(i,9);
		inizSigns(i);
		uebergaenge[i][(int)'(']= 13;
		uebergaenge[i][(int)'<']= 17;
	}

}


int Automat1::uebergang(int zustand, char zeichen){

	if((zustand<(this->zustaende+1)) & ((int)zeichen<(eingabealphabet+1)& (int)zeichen>0)){ // Nur gueltige Eingaben

		return this->uebergaenge[zustand][(int)zeichen];

	} else{
		// cout << "Kein ASCII Zeichen angegeben oder einen Zustand der nicht existiert" << endl; //exception besser
		return this->uebergaenge[20]['+'];

	}


}

void Automat1::inizMixalpha(int zustand, int naechsteZustand){

	for(int i=65; i<91;i++){	// ABC...z
		uebergaenge[zustand][i]= naechsteZustand;
	}

	for(int i=97; i<123;i++){	// abc...z
			uebergaenge[zustand][i]= naechsteZustand;
	}
}

void Automat1::inizDigit(int zustand, int naechsteZustand){

	for(int i=48; i<58;i++){	// 012...9
		uebergaenge[zustand][i]= naechsteZustand;
	}
}

void Automat1::inizSigns(int zustand){
	int zustandN;
	zustandN = 21;
	for(int i=0; !signs[i]=='\0'; i++){

		uebergaenge[zustand][(int)signs[i]]= zustandN;

		zustandN++;
	}
}


Automat1::~Automat1() {

}
